﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Facebook;
using ThangNM_LIB.FUNC;
using EntityObject;
using System.Text;
using ThangNM_LIB.EO;
using System.Net;
using HtmlAgilityPack;
using System.Text.RegularExpressions;
using System.IO;

namespace FacebookApp
{
    /// <summary>
    /// Summary description for FacebookProxy
    /// </summary>
    public class FacebookProxy : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            try
            {
                if (context.Request.QueryString["q"] != null && !String.IsNullOrEmpty(context.Request.QueryString["q"]) && CommonsCheck.IsBase64String(context.Request.QueryString["q"]))
                {
                    FacebookProxyEO.RequestEO _RequestEO = new FacebookProxyEO.RequestEO();
                    String q = StringEx.Trim(Encoding.UTF8.GetString(Convert.FromBase64String(StringEx.Trim(context.Request.QueryString["q"]))));
                    var objTemp = JsonEx.Json2Object(q, _RequestEO.GetType());
                    if (objTemp != null)
                    {
                        _RequestEO = (FacebookProxyEO.RequestEO)objTemp;
                        if (_RequestEO != null)
                        {
                            switch (_RequestEO.Type)
                            {
                                case ConstEx.Facebook_HttpMethod.Get:
                                    FacebookClient_Get(ref context, _RequestEO);
                                    return;
                                    break;

                                case ConstEx.Facebook_HttpMethod.Post:
                                    FacebookClient_Post(ref context, _RequestEO);
                                    return;
                                    break;

                                case ConstEx.Facebook_HttpMethod.Delete:
                                    FacebookClient_Delete(ref context, _RequestEO);
                                    return;
                                    break;
                                default:
                                    set_404(context);
                                    return;
                                    break;
                            }
                        }
                    }
                }
                else if (context.Request.QueryString["u"] != null && !String.IsNullOrEmpty(context.Request.QueryString["u"]))
                {
                    Int64 uid = 0;
                    String sUrl = "https://m.facebook.com/" + StringEx.Trim(context.Request.QueryString["u"]);
                    String htmlString = "";
                    using (WebClient client = new WebClient())
                    {
                        client.Encoding = Encoding.UTF8;
                        client.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.111 Safari/537.36");
                        htmlString = client.DownloadString(sUrl);
                        if (!String.IsNullOrEmpty(htmlString))
                        {
                            MatchCollection mclTemp = Regex.Matches(htmlString, "(?<=\"entity_id\":)(\\d+)", RegexOptions.Singleline);
                            htmlString = StringEx.TrimEx((mclTemp.Count > 0 ? mclTemp[0].Groups[0].Value : null));
                            Int64.TryParse(htmlString, out uid);
                        }
                        if (uid <= 0)
                        {
                            sUrl = "https://www.facebook.com/" + StringEx.Trim(context.Request.QueryString["u"]);
                            htmlString = client.DownloadString(sUrl);
                            if (!String.IsNullOrEmpty(htmlString))
                            {
                                HtmlDocument doc = new HtmlDocument();
                                doc.LoadHtml(htmlString);
                                HtmlNode meta_tag = doc.DocumentNode.SelectSingleNode("//meta[@property='al:android:url']");
                                if (meta_tag == null)
                                    meta_tag = doc.DocumentNode.SelectSingleNode("//meta[@property='al:ios:url']");
                                if (meta_tag != null)
                                    htmlString = meta_tag.Attributes["content"].Value;
                                htmlString = Regex.Match(htmlString, @"\d+").Value;
                                Int64.TryParse(htmlString, out uid);
                            }
                        }
                        if (uid <= 0)
                        {
                            set_404(context);
                            return;
                        }
                    }
                    HttpResponse r = context.Response;
                    r.ContentType = "text/plain; charset=utf-8";
                    r.Write(uid);
                    r.Cache.SetCacheability(HttpCacheability.Public);
                    r.Cache.SetLastModified(DateTime.Now);
                }
                else if (context.Request.QueryString["x"] != null && !String.IsNullOrEmpty(context.Request.QueryString["x"]))
                {
                    String sUrl = "http://www.pornhd.com/videos/" + StringEx.Trim(context.Request.QueryString["x"]) + "/xxx";
                    String htmlString = "";
                    using (WebClient client = new WebClient())
                    {
                        client.Encoding = Encoding.UTF8;
                        client.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.111 Safari/537.36");
                        htmlString = client.DownloadString(sUrl);
                    }
                    HttpResponse r = context.Response;
                    r.ContentType = "text/plain; charset=utf-8";
                    r.Write(htmlString);
                    r.Cache.SetCacheability(HttpCacheability.Public);
                    r.Cache.SetLastModified(DateTime.Now);
                }
                else
                    set_404(context);
            }
            catch (Exception ex)
            {
                (new Logs()).WriteLog_To_DB(new ThangNM_LIB.EO.LogEO(ex.ToString(), ConstEx.Log_iType.EXCEPTION), false);
                context.Response.StatusCode = 400;
                context.Response.StatusDescription = "Bad Request";
            }
        }

        public void set_404(HttpContext context)
        {
            context.Response.StatusCode = 404;
            context.Response.StatusDescription = "Not Found";
        }

        public void FacebookClient_Get(ref HttpContext context, FacebookProxyEO.RequestEO objInput)
        {
            FacebookProxyEO.ResponseEO objOutput = new FacebookProxyEO.ResponseEO();
            HttpResponse r = context.Response;
            r.ContentType = "application/json; charset=utf-8";
            try
            {
                Facebook.FacebookClient FBClient = new FacebookClient();
                FBClient.AccessToken = objInput.AccessToken;
                FBClient.AppId = objInput.AppId;
                FBClient.AppSecret = objInput.AppSecret;
                //FBClient.DefaultVersion = objInput.DefaultVersion;
                FBClient.IsSecureConnection = objInput.IsSecureConnection;
                FBClient.SubscriptionVerifyToken = objInput.SubscriptionVerifyToken;
                FBClient.UseFacebookBeta = objInput.UseFacebookBeta;
                FBClient.Version = objInput.Version;

                objOutput.Content = Convert.ToString(FBClient.Get(objInput.Query));
                objOutput.Error = "";
            }
            catch (Exception ex)
            {
                (new Logs()).WriteLog_To_DB(new ThangNM_LIB.EO.LogEO(ex.ToString(), ConstEx.Log_iType.EXCEPTION), false);
                objOutput.Content = "";
                objOutput.Error = ex.ToString();
            }
            r.Write(Convert.ToBase64String(Encoding.UTF8.GetBytes(JsonEx.Object2Json(objOutput))));
            r.Cache.SetCacheability(HttpCacheability.Public);
            r.Cache.SetLastModified(DateTime.Now);
        }

        public void FacebookClient_Post(ref HttpContext context, FacebookProxyEO.RequestEO objInput)
        {
        }

        public void FacebookClient_Delete(ref HttpContext context, FacebookProxyEO.RequestEO objInput)
        {
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}